/*
 * @Author: qinuoyun
 * @Date:   2021-09-15 22:43:53
 * @Last Modified by:   qinuoyun
 * @Last Modified time: 2021-09-23 22:27:15
 */
//初始化常量
require('./system/initialize.js')
require('./system/functions.js')
require('./system/config/common.js')

process.env.PORT = C("port");

//初始化数据库插件
if (C("database") && C("database") == 'mongodb') {
    const _mongodb = require('./system/plugin/mongodb');
    global.db = _mongodb.connect(C("mongodb"));
}
//初始化全局控制器类
global.BasicController = require('./system/common/BasicController.js');

//初始化全局模型类
global.CommonModels = require('./system/common/CommonModels.js');

//初始化HTTP请求工具
const _request = require('./system/plugin/request/index.js');
global.request = new _request();

//初始化secret用于JWT鉴权使用保证加密和解析的用的是相同的
global.__SECRET__ = C("components.jwt.key");

//加载系统需要数据
const koa = require('koa'),
    fs = require('fs'),
    logger = require('koa-logger'),
    json = require('koa-json'),
    views = require('koa-views'),
    koaJwt = require('koa-jwt'),
    bodyParser = require("koa-bodyparser"),
    socket = require('./system/plugin/socket'),
    error = require('./system/plugin/error');

const app = new koa();


//设置KOA视图加载目录
app.use(views(__dirname + '/views', {
    extension: 'ejs'
}))

//加载JSON中间件
app.use(json());
//获取数据内容
app.use(bodyParser());
//错误信息收纳器
app.use(error());
//加载日志中间件
app.use(logger());

//处理运行时间
app.use(async (ctx, next) => {
    const start = new Date()
    await next()
    const ms = new Date() - start
    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})

// 设置静态目录
app.use(require('koa-static')(__dirname + '/src/public'));

// 加载路由信息
var index = require('./system/views');
app.use(index.routes(), index.allowedMethods())

//JWT中间件
app.use(koaJwt({
    secret: __SECRET__
}).unless({
    //设置白名单信息
    path: ["/favicon.ico"].concat(C("whitelist"))
}));

//鉴权通过后执行的数据用户数据交换
app.use(async (ctx, next) => {
    try {
        //读取用户信息类
        let identityClass = require(ROOT_DIR + DS + 'src' + DS + C("components.user.identityClass"));
        //判断是否是函数
        if (Object.prototype.toString.call(identityClass) == "[object Function]" && ctx.request.header.authorization) {
            if (identityClass.findIdentityByAccessToken && Object.prototype.toString.call(identityClass.findIdentityByAccessToken) == "[object Function]") {
                let userinfo = await identityClass.findIdentityByAccessToken(ctx.request.header.authorization);
                ctx.state = {
                    user: userinfo
                }
                await next();
            }
        } else {
            await next();
        }
    } catch (error) {
        throw error;
    }
});


// 加载API路由
var API = require('./system/plugin/api');
app.use(API.routes(), API.allowedMethods());


// 创建一个链接库，需要在WWW中后置运行
app.__socket = function(app, server) {
    const io = new socket();
    io.attach(app, server);
    //判断是否需要开启IO链接
    if (C("components.socket.enableConnection")) {
        try {
            let caomponent = getComponent(C("components.socket.class"));
            //获取所有链接的方法名
            let connections = Object.getOwnPropertyNames(caomponent.prototype);
            app._io.on('connection', socket => {
                console.log('建立连接了');
                //实力话组建对象
                let socketClass = new caomponent(socket);
                //循环创建会话
                for (let index in connections) {
                    let action = connections[index];
                    let onAction = action.match(/action([\w]+)/);
                    if (onAction && onAction[1]) {
                        console.log("action", onAction[1], action)
                        //接收数据
                        socket.on(onAction[1], async function(data) {
                            socketClass[action](socket, data)
                        });
                    }
                }
            })

        } catch (error) {
            throw error;
        }
    }
}

module.exports = app;